package com.gwnet.shop.service.impl;

import java.util.*;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.gwnet.common.core.utils.StringUtils;
import com.gwnet.common.satoken.utils.LoginHelper;
import com.gwnet.rider.service.PlatformWalletLogService;
import com.gwnet.rider.service.RiderWalletService;
import com.gwnet.shop.domain.*;
import com.gwnet.shop.domain.bo.OrderInfoBo;
import com.gwnet.shop.domain.bo.SpecGroupBo;
import com.gwnet.shop.domain.vo.OrderInfoVo;
import com.gwnet.shop.domain.vo.SpecGroupVo;
import com.gwnet.shop.enums.OrderConstants;
import com.gwnet.shop.enums.OrderStatusEnum;
import com.gwnet.shop.mapper.*;
import com.gwnet.shop.service.IUserBuyTenantService;
import com.gwnet.shop.service.ShopWalletService;
import com.gwnet.shop.utils.UniqueStringGenerator;
import org.springframework.stereotype.Service;
import com.gwnet.shop.service.IOrderInfoService;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;

/**
 * 订单Service业务层处理
 *
 * @author 张万鹏
 * @date 2024-07-29
 */
@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper,OrderInfo> implements IOrderInfoService {
    @Resource
    private OrderInfoMapper orderInfoMapper;

    @Resource
    private ShopGoodsMapper shopGoodsMapper;

    @Resource
    private SpecGroupMapper specGroupMapper;

    @Resource
    private ShopAddressMapper shopAddressMapper;

    @Resource
    private OrderDeliveryMapper orderDeliveryMapper;

    @Resource
    private OrderGoodsMapper orderGoodsMapper;

    @Resource
    private OrderPaymentMapper orderPaymentMapper;

    @Resource
    private  ExecutorService taskExecutor;

    @Resource
    private IUserBuyTenantService userBuyTenantService;

    @Resource
    private SysTenantMapper tenantMapper;

    @Resource
    private FeeStandardMapper feeStandardMapper;

    @Resource
    private PlatformWalletLogService platformWalletLogService;

    @Resource
    private RiderWalletService riderWalletService;

    @Resource
    private ShopWalletService shopWalletService;



    /**
     * 查询订单
     *
     * @param orderId 订单主键
     * @return 订单
     */
    @Override
    public OrderInfo selectOrderInfoByOrderId(String orderId)
    {
        return orderInfoMapper.selectOrderInfoByOrderId(orderId);
    }

    /**
     * 查询订单列表
     * @param orderInfo 订单
     * @return 订单
     */
    @Override
    public List<OrderInfo> selectOrderInfoList(OrderInfo orderInfo)
    {
        return orderInfoMapper.selectOrderInfoList(orderInfo);
    }

    /**
     * 新增订单
     * @param orderInfo 订单
     * @return 结果
     */
    @Transactional
    @Override
    public int insertOrderInfo(OrderInfoBo orderInfo)
    {
        //生成订单
        return generateOrder(orderInfo);
    }

    /**
     * 修改订单
     *
     * @param orderInfo 订单
     * @return 结果
     */
    @Override
    public int updateOrderInfo(OrderInfo orderInfo)
    {
        return orderInfoMapper.updateOrderInfo(orderInfo);
    }

    /**
     * 批量删除订单
     *
     * @param orderIds 需要删除的订单主键
     * @return 结果
     */
    @Override
    public int deleteOrderInfoByOrderIds(String[] orderIds)
    {
        return orderInfoMapper.deleteOrderInfoByOrderIds(orderIds);
    }

    /**
     * 删除订单信息
     *
     * @param orderId 订单主键
     * @return 结果
     */
    @Override
    public int deleteOrderInfoByOrderId(String orderId)
    {
        return orderInfoMapper.deleteOrderInfoByOrderId(orderId);
    }

    /**
     * 查询订单信息 及 对应的 商品 派送信息  支付信息
     * @param orderId 订单主键
     * @return 订单
     */
    @Override
    public OrderInfo selectOrderInfoDetailByOrderId(String orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectOrderInfoByOrderId(orderId);
        if(orderInfo != null){
            //查询对应的商品
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderId(orderInfo.getOrderId());
            List<OrderGoods> goodList = orderGoodsMapper.selectOrderGoodsList(orderGoods);
            orderInfo.setGoods(goodList);
            //查询派送信息
            OrderDelivery orderDelivery = new OrderDelivery();
            orderDelivery.setOrderId(orderInfo.getOrderId());
            List<OrderDelivery> deliveryList = orderDeliveryMapper.selectOrderDeliveryList(orderDelivery);
            orderInfo.setOrderDelivery(deliveryList);
            //查询支付信息
            OrderPayment orderPayment = new OrderPayment();
            orderPayment.setOrderId(orderInfo.getOrderId());
            List<OrderPayment> paymentList = orderPaymentMapper.selectOrderPaymentList(orderPayment);
            orderInfo.setOrderPayment(paymentList);
        }else{
            throw new RuntimeException("未查询到相应订单");
        }
        return orderInfo;
    }

    /**
     *支付成功以后   根据订单id修改订单状态
     * @param orderId 订单id
     * @return
     */
    @Transactional
    @Override
    public int changeOrderStatusByOrderIdPaySuccess(String orderId) {
        OrderInfo orderInfo = orderInfoMapper.selectById(orderId);
        if(orderInfo == null || !OrderStatusEnum.WAIT_PAY.code().equals(orderInfo.getOrderStatus()) ){
            throw new RuntimeException("订单状态错误!");
        }
        orderPaymentMapper.changeStatusById(orderId,OrderStatusEnum.WAIT_RECEIVE_ORDER.code());
        orderDeliveryMapper.changeStatusByOrderId(orderId,OrderStatusEnum.WAIT_RECEIVE_ORDER.code());
        return orderInfoMapper.changeOrderStatusByOrderId(orderId,OrderStatusEnum.WAIT_RECEIVE_ORDER.code());
    }

    /**
     * 查询订单列表 及购买商品
     * @param orderInfo 订单
     * @return 订单集合
     */
    @Override
    public List<OrderInfo> selectOrderInfoListDetail(OrderInfo orderInfo) {
        List<OrderInfo> orderInfos = orderInfoMapper.selectOrderInfoList(orderInfo);
        for(OrderInfo info:orderInfos){
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderId(info.getOrderId());
            List<OrderGoods> goodsList = orderGoodsMapper.selectOrderGoodsList(orderGoods);
            info.setGoods(goodsList);
        }
        return orderInfos;
    }

    @Override
    public Boolean cleanOrderBox(String orderId) {
        Integer count = orderInfoMapper.cleanOrderBox(orderId);
        return count > 0;
    }

    /**
     * 生成订单信息之前,把所有内容查出来进行展示,方便用户下单
     * @param orderInfoBo
     * @return
     */
    @Override
    public OrderInfoVo preGenerateOrder(OrderInfoBo orderInfoBo) {
        //规格组合 及  商品信息
        List<SpecGroupBo> list = orderInfoBo.getList();
        List<SpecGroupVo> groups = new ArrayList<>();

        //打包费
        double totalPackageMoney = 0.0;
        //商品费用
        double totalGoodsMoney = 0.0;
        for(SpecGroupBo groupBo:list){
            Long specGroupId = groupBo.getSpecGroupId();

            SpecGroup specGroup = specGroupMapper.selectSpecGroupById(specGroupId);
            ShopGoods shopGoods = shopGoodsMapper.selectShopGoodsById(specGroup.getGoodsId());
            specGroup.setShopGoods(shopGoods);
            Integer quantity = groupBo.getQuantity();

            totalPackageMoney += specGroup.getPackageMoney()*quantity;
            totalGoodsMoney += specGroup.getPrice()*quantity;

            SpecGroupVo groupVo = new SpecGroupVo();
            groupVo.setSpecGroup(specGroup);
            groupVo.setQuantity(quantity);
            groups.add(groupVo);
        }
        double goodsAmount = orderInfoBo.getGoodsAmount();
        if(goodsAmount != totalGoodsMoney){
            throw new RuntimeException("订单金额有误!");
        }
        OrderInfoVo infoVo = new OrderInfoVo();
        //查询收货地址
        ShopAddress shopAddress = shopAddressMapper.selectShopAddressById(orderInfoBo.getAddressId());
        infoVo.setAddress(shopAddress);

        //店铺名称
        SysTenant sysTenant = tenantMapper.selectSysTenantById(orderInfoBo.getTenantId());
        infoVo.setTenantName(sysTenant.getCompanyName());

        infoVo.setGroups(groups);
        infoVo.setTotalPackageMoney(totalPackageMoney);
        double deliverAmount = feeStandardMapper.getAmount(goodsAmount);
        infoVo.setDeliverAmount(deliverAmount);
        infoVo.setGoodsAmount(totalGoodsMoney);
        return infoVo;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void orderCommissionSettlement(List<OrderInfo> orders) {
        List<String> orderIds = orders.stream().map(OrderInfo::getOrderId).collect(Collectors.toList());
        if (CollUtil.isEmpty(orderIds)) {
            return;
        }
        // 众所周知，结算之后是不能改变状态的
        LambdaUpdateWrapper<OrderInfo> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.in(OrderInfo::getOrderId,orderIds);
        updateWrapper.set(OrderInfo::getIsSettled,1);
        int count = baseMapper.update(updateWrapper);
        if (count == 0) {
            return;
        }
        for (OrderInfo order : orders) {
            // 结算给商家增加金额，商家
            shopWalletService.addAmountBySettledOrder(order);

            // 结算给骑手增加金额
            riderWalletService.addAmountBySettledOrder(order);
        }

    }

    /**
     * 修改订单 order_info表的状态
     * @param delivery
     */
    @Override
    public void changeOrderStatusByOrderId(OrderDelivery delivery) {
        OrderInfo orderInfo = orderInfoMapper.selectById(delivery.getOrderId());
        orderInfo.setOrderStatus( delivery.getDeliveryStatus() );
        orderInfo.setUpdateTime(new Date());
        if(OrderStatusEnum.SUCCESS.code().equals(delivery.getDeliveryStatus())){
            orderInfo.setCompleteTime(new Date());
        }
        orderInfoMapper.updateById(orderInfo);
    }

    /**
     * 生成订单
     * @param orderInfoBo
     * @return
     */
    private int generateOrder(OrderInfoBo orderInfoBo) {

        long start = System.currentTimeMillis();
        List<SpecGroupBo> list = orderInfoBo.getList();
        String orderId = UniqueStringGenerator.generateUniqueString(20);
        String deliveryId = UniqueStringGenerator.generateUniqueString(20);

        //打包费
        double totalPackageMoney = 0.0;
        //商品费用
        double totalGoodsMoney = 0.0;

        String paymentTitle = "";
        for(SpecGroupBo s:list){

            //specGroupId 规格组合Id
            Long specGroupId = s.getSpecGroupId();
            Integer quantity = s.getQuantity();

            //根据规格组合id查询 规格组合
            SpecGroup group = specGroupMapper.selectSpecGroupById(specGroupId);
            //商品id
            Long goodsId = group.getGoodsId();
            //shopGoods 商品
            ShopGoods shopGoods = shopGoodsMapper.selectShopGoodsById(goodsId);
            //---------------- 生成订单商品信息 ordergoods ---------------------------------
            OrderGoods orderGoods = new OrderGoods();
            orderGoods.setOrderId(orderId);
            orderGoods.setGoodsId(goodsId);
            orderGoods.setSpceGroupId(specGroupId);
            orderGoods.setGoodsTitle(shopGoods.getName());
            orderGoods.setSpecText(group.getSpecText());
            orderGoods.setShowUrl(shopGoods.getShowUrl());
            orderGoods.setImgUrl(group.getImgUrl());
            orderGoods.setSellPrice(group.getPrice());
            orderGoods.setPackageMoney(group.getPackageMoney() * quantity);
            orderGoods.setQuantity(quantity);

            totalPackageMoney += group.getPackageMoney()*quantity;
            totalGoodsMoney += group.getPrice()*quantity;

            paymentTitle += shopGoods.getName()+",";
            orderGoodsMapper.insertOrderGoods(orderGoods);
        }
        if(orderInfoBo.getGoodsAmount() != totalGoodsMoney){
            long end = System.currentTimeMillis();
            System.out.println("++++++++++++++++++++++++++++++++++"+(end-start));
            throw new RuntimeException("商品金额有误!");
        }
        if(orderInfoBo.getTotalPackageMoney() != totalPackageMoney){
            throw new RuntimeException("打包费金额有误!");
        }
        double deliverAmount = feeStandardMapper.getAmount(orderInfoBo.getGoodsAmount());
        if(orderInfoBo.getDeliverAmount() != deliverAmount){
            throw new RuntimeException("配送费金额有误!");
        }
        double totalOrderAmount = orderInfoBo.getGoodsAmount() + orderInfoBo.getTotalPackageMoney() + deliverAmount;

        //---------------- 生成支付信息 orderpayment ---------------------------------
        Long userId = orderInfoBo.getUserId();
        OrderPayment payment = new OrderPayment();
        payment.setUserId(userId);
        payment.setOrderId(orderId);
        payment.setPaymentTitle(paymentTitle);
        payment.setPaymentAmount(totalOrderAmount);
        payment.setStatus("0");
        payment.setPaymentType("0");
        orderPaymentMapper.insertOrderPayment(payment);

        //---------------- 生成派送单信息 orderdelivery ---------------------------------
        Long addressId = orderInfoBo.getAddressId();
        ShopAddress shopAddress = shopAddressMapper.selectShopAddressById(addressId);
        OrderDelivery delivery = new OrderDelivery();
        delivery.setId(deliveryId);
        delivery.setOrderId(orderId);
        delivery.setAcceptName(shopAddress.getAcceptName());
        delivery.setMobile(shopAddress.getMobile());
        delivery.setAddress(shopAddress.getAddress());
        delivery.setDeliverAmount(deliverAmount);
        delivery.setDeliveryStatus("0");
        orderDeliveryMapper.insertOrderDelivery(delivery);

        //---------------- 生成订单信息 orderinfo ---------------------------------
        Long tenantId = orderInfoBo.getTenantId();
        OrderInfo info = new OrderInfo();
        info.setOrderId(orderId);
        info.setTenantId(tenantId);
        SysTenant sysTenant = tenantMapper.selectSysTenantById(tenantId);
        info.setSchoolId(sysTenant.getSchoolId());
        info.setUserId(userId);
        info.setTotalPackageMoney(orderInfoBo.getTotalPackageMoney());
        info.setDeliverAmount(deliverAmount);
        info.setGoodsAmount(orderInfoBo.getGoodsAmount());

        info.setOrderAmount(totalOrderAmount);
        info.setAddTime(new Date());
        info.setPostscript(orderInfoBo.getPostscript());
        info.setDeliveryId(deliveryId);
        info.setOrderStatus("0");
        info.setUserName(LoginHelper.getUsername());
        info.setCreateTime(new Date());

        //---------------- 生成财务信息 platformWalletLog ---------------------------------
        Boolean genFlag = platformWalletLogService.genWalletLog(info,delivery);

        //开启新线程执行 插入到我 买过 的店铺表
        UserBuyTenant ubt = new UserBuyTenant();
        ubt.setUserId(userId);
        ubt.setTenantId(tenantId);
        taskExecutor.submit(() -> {
            userBuyTenantService.insertUserBuyTenant(ubt);
        });
        return orderInfoMapper.insertOrderInfo(info);
    }


}
